package pl.com.qapps.unity;

import java.util.Objects;

import org.gnome.gtk.Menu;

import pl.com.qapps.unity.IndicatorPb.IndicatorEvent.Property;
import pl.com.qapps.unity.IndicatorPb.IndicatorEvent.Value;

/**
 * @author Jakub Dykowski
 * 
 */
public final class AppIndicator {

	private final IndicatorProxy proxy;
	private final Category category;
	private final String id;
	private Menu menu;

	/**
	 * 
	 * @param id
	 * @param iconName
	 * @param category
	 * @throws IllegalArgumentException
	 */
	public AppIndicator(String id, String iconName, Category category)
			throws IllegalArgumentException {
		this.id = Objects.requireNonNull(id, "id cannot be null");
		this.category = Objects.requireNonNull(category,
				"category cannot be null");
		proxy = new IndicatorProxy(id, iconName, category);
	}

	public AppIndicator(String id, String iconName, Category category,
			String iconThemePath) {
		// TODO implement indicator with icon theme path
		throw new UnsupportedOperationException("not supported yet");
	}

	public Category getCategory() {
		return category;
	}

	public int getOrderingIndex() {
		return proxy.get(Property.ORDERING_INDEX).getInt();
	}

	public AppIndicator setOrderingIndex(int orderingIndex) {
		proxy.set(Property.ORDERING_INDEX,
				Value.newBuilder().setInt(orderingIndex).build());
		return this;
	}

	public Status getStatus() {
		return getStatusFromString(proxy.get(Property.STATUS).getString());
	}

	public AppIndicator setStatus(Status status) {
		proxy.set(Property.STATUS,
				Value.newBuilder().setString(status.getStringValue()).build());
		return this;
	}

	public boolean isConnected() {
		return proxy.get(Property.CONNECTED).getBool();
	}

	public String getTitle() {
		return proxy.get(Property.TITLE).getString();
	}

	public AppIndicator setTitle(String title) {
		proxy.set(Property.TITLE, Value.newBuilder().setString(title).build());
		return this;
	}

	public String getLabel() {
		return proxy.get(Property.LABEL).getString();
	}

	public AppIndicator setLabel(String label) {
		proxy.set(Property.LABEL, Value.newBuilder().setString(label).build());
		return this;
	}

	public String getLabelGuide() {
		return proxy.get(Property.LABEL_GUIDE).getString();
	}

	public AppIndicator setLabelGuide(String labelGuide) {
		proxy.set(Property.LABEL_GUIDE, Value.newBuilder()
				.setString(labelGuide).build());
		return this;
	}

	public String getAttentionIconDesc() {
		return proxy.get(Property.ATTENTION_ICON_DESC).getString();
	}

	public AppIndicator setAttentionIconDesc(String desc) {
		proxy.set(Property.ATTENTION_ICON_DESC,
				Value.newBuilder().setString(desc).build());
		return this;
	}

	public String getAttentionIconName() {
		return proxy.get(Property.ATTENTION_ICON_NAME).getString();
	}

	public AppIndicator setAttentionIconName(String iconName) {
		proxy.set(Property.ATTENTION_ICON_NAME,
				Value.newBuilder().setString(iconName).build());
		return this;
	}

	public String getIconDesc() {
		return proxy.get(Property.ICON_DESC).getString();
	}

	public AppIndicator setIconDesc(String desc) {
		proxy.set(Property.ICON_DESC, Value.newBuilder().setString(desc)
				.build());
		return this;
	}

	public String getIconName() {
		return proxy.get(Property.ICON_NAME).getString();
	}

	public AppIndicator setIconName(String iconName) {
		proxy.set(Property.ICON_NAME, Value.newBuilder().setString(iconName)
				.build());
		return this;
	}

	public String getIconThemePath() {
		return proxy.get(Property.ICON_THEME_PATH).getString();
	}

	public String getId() {
		return id;
	}

	public Menu getMenu() {
		return menu;
	}
	
	public AppIndicator setMenu(Menu menu) {
		this.menu = menu;
		return this;
	}

	@Override
	public String toString() {
		return "<AppIndicator " + getId() + ">";
	}

	private static Status getStatusFromString(String status) {
		switch (status) {
		case "0":
			return Status.PASSIVE;
		case "1":
			return Status.ACTIVE;
		case "2":
			return Status.ATTENTION;
		default:
			// TODO make better exception handling
			throw new RuntimeException(
					"Unknown status, most likely this is implementation oversight");
		}
	}

	public enum Category {

		APPLICATION_STATUS, COMMUNICATION, SYSTEM_SERVICE, HARDWARE, OTHER;
	}

	public enum Status {

		PASSIVE("0"), ACTIVE("1"), ATTENTION("2");

		private String stringValue;

		private Status(String value) {
			this.stringValue = value;
		}

		private String getStringValue() {
			return stringValue;
		}
	}
	
	public static void main(String[] args) {
		AppIndicator ind = new AppIndicator("pl.com.gdrive", "folder-home",
				Category.APPLICATION_STATUS);
		ind.setTitle("hello gdrive");
	}
}
